package cn.freeprogrammer.igen.data.type;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
 * 字段类型工具类，提供根据JDBC类型获取字段类型对象的操作.
 * 
 * @author minwh
 *
 */
public class FieldTypeUtils {
	
	private final static String TYPES_XML_CLASSPATH = "types.xml";
	
	private static Map<Integer, FieldType> fieldTypeMap = null;
	
	/**
	 * 根据JDBC类型获取字段类型对象.
	 */
	public static synchronized FieldType getFieldType(Integer jdbcType) {
		if (fieldTypeMap == null) {
			init();
		}
		
		return fieldTypeMap.get(jdbcType);
	}
	
	private static void init() {
		fieldTypeMap = new HashMap<Integer, FieldType>();
		
		String configFile = FieldTypeUtils.class.getResource(TYPES_XML_CLASSPATH).getFile();
		
		try {
			SAXReader reader = new SAXReader();
			Document document = reader.read(configFile);
			Element root = document.getRootElement();
			
			Iterator iter = root.element("javaTypes").elementIterator("javaType");
			Map<String, JavaType> javaTypeMap = new HashMap<String, JavaType>();
			while (iter.hasNext()) {
				Element e = (Element) iter.next();
				String name = e.attributeValue("name");
				String fullName = e.attributeValue("fullName");
				Boolean needsImport = Boolean.valueOf(e.attributeValue("needsImport"));
				javaTypeMap.put(name, new JavaType(name, fullName, needsImport));
			}
	
			iter = root.element("jdbcTypes").elementIterator("jdbcType");
			Map<Integer, JdbcType> jdbcTypeMap = new HashMap<Integer, JdbcType>();
			while (iter.hasNext()) {
				Element e = (Element) iter.next();
				Integer id = Integer.valueOf(e.attributeValue("id"));
				String name = e.attributeValue("name");
				jdbcTypeMap.put(id, new JdbcType(id, name));
			}
	
			iter = root.element("fieldTypes").elementIterator("fieldType");
			while (iter.hasNext()) {
				Element e = (Element) iter.next();
				Integer jdbcType = Integer.valueOf(e.attributeValue("jdbcType"));
				String javaType = e.attributeValue("javaType");
				fieldTypeMap.put(jdbcType, new FieldType(jdbcTypeMap.get(jdbcType), javaTypeMap
						.get(javaType)));
			}
		}catch(Exception e) {
			throw new RuntimeException(e);
		}
	}
}
